# -*- coding:utf8 -*-
#encoding = utf-8
__author__ = 'man' 

#		_________________________________________________________________________________
#
#						漫鸽网络技术服务(mangenotwork)拥有所有权
#						@www.hbsj.xyz   
#						@www.mangenotwork.com
#			严重声明：原始代码属于"漫鸽网络技术服务(mangenotwork)"的知识产权，拥有法律的保护，
#		请勿抄袭、转载、删除、私用、篡改、破坏...
#
#       
#		简介 ：  login.py 登陆注册API
#		作者 ： 李漫(man)
#		创建时间:  20190620
#		
#		_________________________________________________________________________________



from flask import Flask,request,g,render_template,redirect,url_for,abort,session,jsonify,current_app
from flask import Blueprint , render_template
from flask import make_response,Response 
#文件上传下载
from werkzeug import secure_filename
from werkzeug.utils import secure_filename

import sys,os
import json
import time
import datetime
import redis
from cryptography.fernet import Fernet
import random
#md5
import hashlib
#使用公用方法
import api.public as pub
import db.mandb

# 阿里短信
import api.dysms_python.demo_sms_send as smssend

smssend.test()
#smssend.send_sest("18483663083","5252")

#图片处理功能
import api.compress_img as compress

'''
man_db = db.mandb.DB()
print(man_db.db_connect())
'''
login = Blueprint('login',__name__)

#函数不能命名 test


'''
					#类型： DB交互
					#执行查询  查询结果
'''
def ManDB(func=None, param=None):
	def deco(func):
		def wrapper(*args,**kwargs):
			man_db = db.mandb.DB()
			return func(man_db,*args,**kwargs)			
		wrapper.__name__ = func.__name__
		return wrapper
	return deco if not func else deco(func)


'''
					#类型 : 函数，方法
					#设置用户的uuid
'''
def set_user_uuid(src):
	m2 = hashlib.md5()   
	m2.update(src.encode('utf-8'))   
	useruuid = m2.hexdigest()
	return useruuid


'''
					#类型： DB交互
					#添加新用户
'''
@ManDB
def add_hbsj_user(man_db,uuid,acc,name,password):
	ticks = time.time()
	'''
	hbsj_user_uuid char(100) NOT NULL,
	hbsj_user_acc char(20)  NOT NULL,
	hbsj_user_name char(10) NOT NULL,
	hbsj_user_paws char(20) NOT NULL,
	hbsj_user_head varchar(300) NOT NULL DEFAULT "0",
	reg_time char(35) NOT NULL,
	'''
	sql = "INSERT INTO hbsj_user_1 \
	( hbsj_user_uuid, hbsj_user_acc,hbsj_user_name,hbsj_user_paws,reg_time) \
	VALUES ( '"+uuid+"', '"+acc+"', '"+name+"', '"+password+"', '"+str(ticks)+"');"
	man_db.execute(sql)
	return uuid


'''
					#类型： DB交互
					#判断账号是否存在  改为验证 uuid
'''
@ManDB
def useracc_yesno(man_db,accdata):
	sql  = "select hbsj_user_uuid from hbsj_user_1 where hbsj_user_uuid = '"+accdata+"';"
	return_datas = man_db.execute_seles(sql)
	print(len(return_datas))
	return len(return_datas)


'''
					#类型 : 接口
					#用户注册接口
					#使用者: wap
'''
@login.route('/reguser', methods=['POST','GET'])
def reg_user():
	resp = make_response()
	resp.status_code = 200
	if request.method == "POST":
		datax = request.form.to_dict()
	useracc = datax["acc"]
	username = datax["name"]
	userpassword = datax["pswd"]
	#如果用户没有输入用户名  则统一重命名为 尊贵的新用户
	if username =="":
		username = "尊贵的新用户"
	user_uuid = pub.set_user_uuid(useracc)
	#如果账号不存在则创建新用户，否则提示账号存在
	if useracc_yesno(user_uuid) == 0:
		#新建用户
		returnuuid = add_hbsj_user(user_uuid,useracc,username,userpassword)
		#颁发
		#客户端颁发 Key
		#服务器存 加密串
		user_Token,user_Token_key = pub.man_token_create(returnuuid)
		#print(user_Token)
		#print(user_Token_key)
		#print(pub.man_token_decode2(user_Token,user_Token_key))
		#返回新的 cookie 保存 token
		resp.set_cookie('user_token',user_Token,max_age=3600)
		resp.set_cookie('user_name',username,max_age=3600)
		resp.set_cookie('user_acc',useracc,max_age=3600)
		#print("user_token = " + user_Token)
		#print("user_name = " + username)
		#存入seeion
		session[user_Token] = username
		session[useracc] = returnuuid
		returndata = 1
	else:
		returndata = 0
	resp.response = json.dumps(returndata).encode('utf-8').decode("unicode-escape")
	return resp


'''
					#类型： DB交互
					#用户登陆 sql 验证
'''
@ManDB
def verify_acc(man_db,phonenumber,authcode):
	sql = "select auth_val from userauth where phone = '"+phonenumber+"';"
	return_datas = man_db.execute_seles(sql)
	if authcode == return_datas[0][0]:
		return True
	else:
		return False



'''
					#类型： DB交互
					#判断用户是否注册（是否设置过个人信息）
'''
@ManDB
def user_have(man_db,uuid):
	sql = "select user_name from userinfo where user_uuid = '"+uuid+"';"
	return_datas = man_db.execute_seles(sql)
	return return_datas




'''
					#类型： DB交互
					#创建初始化用户
'''
'''
user_uuid char(100) NOT NULL,/* user_uuid  md5 值id   主(不可重复) */
	user_phone char(11) NOT NULL,/* user_phone  电话号码，账号 */
	user_name char(23) NOT NULL,/* user_phone  用户名 */
	user_head varchar(200) NOT NULL DEFAULT "0",/* user_phone  用户头像 默认0 为系统头像 */
	user_ages INT NOT NULL DEFAULT 0,/* user_ages 用户年龄段   默认0 为系统默认年龄段*/
	user_jifen INT  NOT NULL DEFAULT 0,/* user_jifen 用户积分   默认为 0  */
	user_starttime char(20) NOT NULL,/* user_starttime 用户第一次使用的时间  */
'''
@ManDB
def add_userinit(man_db, uuid, phone):
	print(uuid)
	print(phone)
	user_name = "尊贵的新用户"
	user_starttime = str(time.time())
	sql = "INSERT INTO userinfo \
	( user_uuid, user_phone, user_name, user_starttime) \
	VALUES ( '"+uuid+"', '"+phone+"', '"+user_name+"', '"+user_starttime+"');"
	man_db.execute(sql)
	print("[DeBug] add_userinit")
	return 0



'''
					#类型 : 接口
					#用户登录验证接口
					#使用者: wap

					未使用。。。
'''
@login.route('/userlogin', methods=['POST','GET'])
def login_user():
	resp = make_response()
	resp.status_code = 200
	if request.method == "POST":
		datax = request.form.to_dict()

	phone = datax["phonenumber"]
	authcode = datax["authcode"]
	#print(useracc)
	#print(userpassword)
	#验证用户是否账号密码是否正确，如果正确则返回 用户名和 uuid
	vacc = verify_acc(phone,authcode)
	#print(vacc)
	#print(username)
	#print(returnuuid)
	if vacc == True :
		#设置uuid
		uuid = pub.set_user_uuid(phone)
		user_Token,user_Token_key = pub.man_token_create(uuid)
		print(user_Token)
		print(user_Token_key)

		#判断用户是否注册（是否设置过个人信息）
		#系统默认用户不能命名为 【尊贵的新用户】
		username = user_have(uuid)
		print("function user_have() callback : "+str(username))
		if username ==():
			#创建用户,并初始化用户数据
			add_userinit(uuid,phone)
			#注册跳转    返回状态 2
			returndata = 2
			print("22222")
			print("user_name = " + "尊贵的新用户")
			username = "尊贵的新用户"
		
		elif username[0][0] == "尊贵的新用户":
			returndata = 2
			print("22222")
			print("user_name = " + "尊贵的新用户")
			username = "尊贵的新用户"

		else:	
			#身份验证通过颁发  
			# 用户登陆成功，并用户更换过用户信息, 返回状态 1
			returndata = 1
			username = username[0][0]

		print("[username data] = "+username)
		resp.set_cookie('user_token',user_Token,max_age=3600*48)
		resp.set_cookie('user_uuid',uuid,max_age=3600*48)
		resp.set_cookie('user_name',username,max_age=3600*48)
		session[uuid] = user_Token
		session[user_Token] = username
		session[username] = user_Token_key


	else:
		# 用户登陆验证失败   返回状态 0
		returndata = 0
	print("返回 ： "+ str(returndata))
	resp.response = json.dumps(returndata).encode('utf-8').decode("unicode-escape")
	return resp





'''
					#类型 : 接口
					#注册  (填写个人信息)
					#使用者: wap

					#注册  (填写个人信息)
'''
@login.route('/reg', methods=['POST','GET'])
def reg_pg():
    return render_template('reg.html',my=1)





'''
					#类型 : 接口
					#初始化设置名称
					#使用者: wap

					#初始化设置名称
'''
@login.route('/setname', methods=['POST','GET'])
def set_name():
    return render_template('set_name.html',my=1)




'''
					#类型： DB交互
					#更换用户名称
'''
@ManDB
def updata_username(man_db,useruuid, username):
	sql = "UPDATE userinfo \
	set user_name = '"+username+"'\
	where user_uuid = '"+useruuid+"' ;"
	man_db.execute(sql)
	print("[DeBug] updata_username")
	return 0



'''
					#类型： DB交互
					#检查用户名是否存在
'''
@ManDB
def username_yesno(man_db,username):
	sql = "select count(user_name) from userinfo where user_name = '"+username+"';"
	return_datas = man_db.execute_seles(sql)
	return return_datas[0][0]



'''
					#类型： DB交互
					#获取用户主页信息
'''
@ManDB
def get_user_myinfo(man_db,uuid):
	sql = "select user_name from userinfo where user_name = '"+username+"';"
	return_datas = man_db.execute_seles(sql)
	return return_datas[0][0]



'''
					#类型 : 接口
					#初始化设置名称
					#使用者: wap

					#初始化设置名称
'''
@login.route('/setnameapi', methods=['POST','GET'])
def set_name_api():
	resp = make_response()
	resp.status_code = 200
	if request.method == "POST":
		datax = request.form.to_dict()
	name = datax["names"]
	userToken=request.cookies.get('user_token')
	print("userToken = "+ str(userToken))
	useruuid=request.cookies.get('user_uuid')
	print("userUUID = "+ str(useruuid))
	session_usertoken = session.get(useruuid)# 这个是保存的 user_token
	print("session_usertoken = "+ str(session_usertoken))
	if session_usertoken == userToken and userToken != None:
		if len(name) >1 and len(name) <10 and name != "尊贵的新用户":
			if username_yesno(name) == 0:
				updata_username(useruuid,name)
				returndata = 1
			else:
				returndata = 0
		else:
			returndata = 3
	else:
		returndata = 2#异常请求
	print("返回 ： "+ str(returndata))
	resp.response = json.dumps(returndata).encode('utf-8').decode("unicode-escape")
	return resp





'''
					#类型 : 接口
					#初次使用设置个人信息
					#使用者: wap

					#初次使用设置个人信息
'''
@login.route('/setuserinfo', methods=['POST','GET'])
def set_userinfo():
	if pub.userACC() == False:
		return redirect('/')
	else:
		return render_template('set_userinfo.html',my=1)



#更换用户信息
@ManDB
def updata_userinfo(man_db,useruuid, user_head,user_ages):
	sql = "UPDATE userinfo \
	set user_head = '"+user_head+"',\
	user_ages = '"+user_ages+"'\
	where user_uuid = '"+useruuid+"' ;"
	man_db.execute(sql)
	print("[DeBug] updata_username")
	return 0




'''
					#类型 : 接口
					#初次使用设置个人信息 API 接口
					#使用者: wap

					#初次使用设置个人信息 API 接口
'''
@login.route('/setuserinfoapi', methods=['POST','GET'])
def set_userinfo_api():
	if request.method == 'POST':
		file = request.files['headimg']
		ageval = request.form.get('ageval')
		#projectname = request.form.get('project_name')
		#branchname = request.form.get('branch_name')
		#username = request.form.get('user_handle_name')
	#name = datax["names"]
	print(ageval)
	print(file)
	print(file.filename)

	userToken=request.cookies.get('user_token')
	print("userToken = "+ str(userToken))
	useruuid=request.cookies.get('user_uuid')
	print("userUUID = "+ str(useruuid))
	session_usertoken = session.get(useruuid)# 这个是保存的 user_token
	print("session_usertoken = "+ str(session_usertoken))
	if session_usertoken == userToken and userToken != None:

		if file != "" and compress.allowed_file(file.filename):
			returndata = 1
			newfilename = pub.set_user_uuid(str(time.time()))
			#保存到服务器
			#剪裁 图片
			print(newfilename)
			newfilename_info = compress.compressImg_2(file,newfilename,compress.get_filedis(file.filename))

			print(newfilename_info)

			#更新用户上传的信息

			updata_userinfo(useruuid,newfilename_info,ageval)

		else:
			returndata = 0
	else:
		returndata = 2
	print("返回 ： "+ str(returndata))
	return json.dumps(returndata).encode('utf-8').decode("unicode-escape")






'''
					#类型 : 接口
					# 退出登录  outLogin
					#使用者: wap
'''
@login.route('/outLogin', methods=['POST','GET'])
def out_login():
	try:
		resp = make_response()
		resp.status_code = 200
		userToken=request.cookies.get('user_token')
		#退出登陆则采用清楚 cookie 和 session
		resp.delete_cookie('user_token')
		resp.delete_cookie('user_name')
		resp.delete_cookie('login_time')
		session.pop(userToken)
		resp.response = render_template('return_home.html')
		return resp
	except:
		return render_template('return_home.html')

#获取ip
def get_user_ip():
    print(request.remote_addr)
    return request.remote_addr




'''
					#类型 : 接口
					# 短信登陆接口
					# 使用者: wap
'''
@login.route('/loginpg', methods=['POST','GET'])
def loginpg():
	resp = make_response()
	resp.status_code = 200
	user_Token,user_Token_key = pub.man_token_create(str(random.randint(0,99)))
	print("Token = "+user_Token)
	print("Token_key = "+user_Token_key)
	resp.set_cookie("Token",user_Token_key,max_age=3600)
	session[user_Token_key] = user_Token
	'''
	resp.set_cookie('user_token',user_Token,max_age=3600)
	resp.set_cookie('user_name',username,max_age=3600)
	resp.set_cookie('user_acc',useracc,max_age=3600)
	#print("user_token = " + user_Token)
	#print("user_name = " + username)
	#print("user_acc = " + username)
	#存入seeion
	session[user_Token] = username
	session[useracc] = returnuuid
	'''
	
	resp.response = render_template('userlogin.html',my=1,apiinfo=user_Token)
	return resp


'''
userToken=request.cookies.get('user_token')
    print("[Get Cookies] = "+str(userToken))
    username=request.cookies.get('user_name')
    print("[Get username] = "+str(username))

    keys = session.get(userToken)
    print("[Get keys] = "+str(keys))
    if userToken != None and keys == username:
        return True
    else:
        return False

'''


#验证是否发送过短信
'''
phone char(11) NOT NULL,/* 发短信到手机号码 */
	auth_val char(5) NOT NULL,/* 登陆验证码 */
	auth_time char(20)  NOT NULL,/* 发送时间 */
	auth_info varchar(200) NOT NULL,/* 发送的状态信息 */
'''
@ManDB
def get_phonenumber(man_db,phonenumber):
	sql = "select auth_time from userauth where phone = '"+phonenumber+"';"
	return_datas = man_db.execute_seles(sql)
	return return_datas


#记录发送过的短信
@ManDB
def add_authinfo(man_db,phone, auth_val, auth_time, auth_info):
	sql = "INSERT INTO userauth \
	( phone, auth_val,auth_time,auth_info) \
	VALUES ( '"+phone+"', '"+auth_val+"', '"+auth_time+"', '"+auth_info+"');"
	man_db.execute(sql)
	print("[DeBug] add_authinfo")
	return 0


#更新发送短信时间
@ManDB
def updata_authinfo(man_db,phone, auth_val, auth_time, auth_info):
	sql = "UPDATE userauth \
	set auth_val = '"+auth_val+"',\
	    auth_time = '"+auth_time+"',\
	    auth_info = '"+auth_info+"'\
	where phone = '"+phone+"' ;"
	man_db.execute(sql)
	print("[DeBug] add_authinfo")
	return 0


#记录发送过的短信日志
@ManDB
def add_authinfo_logs(man_db, phone, auth_val, auth_time, auth_info):
	sql = "INSERT INTO userauth_logs \
	( phone, auth_val,log_time,auth_info) \
	VALUES ( '"+phone+"', '"+auth_val+"', '"+auth_time+"', '"+auth_info+"');"
	man_db.execute(sql)
	print("[DeBug] add_authinfo_logs")
	return 0



'''
	利用redis的策略最好
	conn.expire('name',10)
    #设置键的过期时间为10s

'''
#短信发送验证
@login.route('/getauthcode', methods=['POST','GET'])
def getauthcode():
	resp = make_response()
	resp.status_code = 200
	if request.method == "POST":
		datax = request.form.to_dict()
	useracc_phone = datax["acc"]
	api = datax["apiinfo"]
	print(useracc_phone)
	print(api)
	#smssend.send_sest("18483663083","5252")
	userToken=request.cookies.get('Token')
	keys = session.get(userToken)
	print(keys)
	
	if len(useracc_phone) == 11:
		
		if str(keys) == str(api):

			#检查该电话号码是否有发过短信
			#没有直接发送
			#有发送过就要对比上次发送时间， 当前时间-上次时间大于5min 就发送，否则提示等待
			pnhone_auth_time = get_phonenumber(useracc_phone)

			if pnhone_auth_time == ():

				#生成验证码
				auth_val = str(random.randint(0,99999))
				print("ok auth_val = " + auth_val)

				#发送短信功能
				auth_info = smssend.send_sest(useracc_phone,auth_val)
				#auth_info = "okok"
				print("add = " + useracc_phone)
				
				
				auth_time = str(time.time())
				print("auth_time" + auth_time)
				#auth_info = "okok"
				#记录发送过的短信
				add_authinfo(useracc_phone,auth_val,auth_time,auth_info)
				#记录发送过的短信日志
				add_authinfo_logs(useracc_phone,auth_val,auth_time,auth_info)
				#如果短信  isv.BUSINESS_LIMIT_CONTROL 触发天级流控  返回 3
				if "触发天级流控Permits:10" in str(auth_info):
					print("[触发天级流控Permits:10]")
					returndata = 3
					returntime = 0
				else:	
					returndata = 1
					returntime = 300
			else:
				last_time = pnhone_auth_time[0][0]
				print(last_time)
				print("now Time  = " + str(time.time()))
				old_login_time = float(last_time)
				#olad_h = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(old_login_time))
				#olad_h = datetime_struct = datetime.datetime.fromtimestamp(old_login_time)
				#now_time = datetime.datetime.now()
				now_time = time.time()
				print(now_time)
				print(old_login_time)
				#print((now_time-olad_h).seconds)
				mistime = now_time-old_login_time
				print(mistime)
				print(type(mistime))
				if mistime>300:
					#生成验证码
					auth_val = str(random.randint(0,99999))
					print("ok auth_val = " + auth_val)

					# 如果时间大于5分钟，更新该电话号码发送验证码的时间并记录日志
					#发送短信功能
					auth_info = smssend.send_sest(useracc_phone,auth_val)
					#auth_info = "okok"
					auth_time = str(time.time())

					#更新发送短信时间
					updata_authinfo(useracc_phone,auth_val,auth_time,auth_info)
					#记录发送过的短信日志
					add_authinfo_logs(useracc_phone,auth_val,auth_time,auth_info)
					returndata = 1
					returntime = 300
				else:
					# 返回前端验证码已发送，请查看短信，请勿重复发起请求；
					returndata = 2
					returntime = 300 - mistime

		else:
			returndata = "Error"
	
	else:
		returndata = 0
	

	returninfo = {
		"state":returndata,
		"times":int(returntime),
	}
	print("[ 返回值 ] = " + str(returninfo))
	resp.response = json.dumps(returninfo).encode('utf-8').decode("unicode-escape")
	return resp








